package com.ai.image_v1.service.impl;
import com.alibaba.dashscope.aigc.imagesynthesis.*;
import com.ai.image_v1.service.ImageGenerateService;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.JsonUtils;
import com.ai.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**

 图片生成服务实现类（完整版）
 特性：1. 正确使用 @Value 注入配置文件密钥 2. 完全对齐官方示例逻辑 3. 适配若依框架 4. 完善异常处理
 Author: yuzx
 Date: 2025/9/6
 Version: 1.0
 */
@Service
public class ImageGenerateServiceImpl implements ImageGenerateService {
    // 若依框架标准日志对象
    private static final Logger log = LoggerFactory.getLogger(ImageGenerateServiceImpl.class);

    /**
     * 从若依配置文件（application.yml）注入DashScope API密钥
     * 默认值为空字符串，避免配置缺失时启动报错
     */
    @Value("${dashscope.api-key:''}")
    private String apiKey;

    /**
     * 同步生成图片（核心方法，完全对齐SDK官方设计）
     * @param prompt 图片描述（需包含场景、风格、特征，如"皮卡丘骑自行车，水彩风格"）
     * @return 可直接访问的图片URL
     * @throws ApiException SDK接口调用异常（如参数错误、服务不可用）
     * @throws NoApiKeyException API密钥缺失异常
     */
    @Override
    public String generateImage(String prompt) throws ApiException, NoApiKeyException {
        log.info("---开始同步调用图片生成API，请等待----");
        log.info("图片描述：{}", prompt);

        // 1. 构建API请求参数（严格遵循SDK参数规范）
        ImageSynthesisParam param = ImageSynthesisParam.builder()
                .apiKey(getEffectiveApiKey()) // 优先级：配置文件 > 环境变量
                .model(ImageSynthesis.Models.WANX_V1) // 官方推荐模型（万象大模型）
                .prompt(prompt) // 图片文字描述
                .style("<watercolor>") // 风格：水彩画（可选值：<oil_painting>油画/<cartoon>卡通等）
                .n(1) // 生成图片数量（1-4，官方限制）
                .size("1024*1024") // 图片尺寸（官方支持：512x512/1024x1024/1024x1536等，需用x分隔）
                .build();

        // 2. 初始化SDK客户端并调用API
        ImageSynthesis imageSynthesisClient = new ImageSynthesis();
        ImageSynthesisResult apiResult = null;
        try {
            apiResult = imageSynthesisClient.call(param); // 阻塞调用，等待结果
        } catch (ApiException e) {
            log.error("API调用失败（接口异常）：{}", e.getMessage());
            throw e; // 抛出原生异常，由控制器统一处理
        } catch (NoApiKeyException e) {
            log.error("API调用失败（密钥缺失）：{}", e.getMessage());
            throw e;
        }

        // 3. 打印完整响应（调试用，生产环境可注释）
        log.debug("API完整响应：{}", apiResult.toString());

        // 4. 解析响应并返回图片URL
        return parseApiResponse(apiResult);
    }

    /**
     * 获取有效API密钥（优先级：配置文件 > 系统环境变量）
     * @return 非空的API密钥
     * @throws NoApiKeyException 密钥缺失时抛出
     */
    private String getEffectiveApiKey() throws NoApiKeyException {
        // 优先使用若依配置文件中的密钥
        if (StringUtils.isNotEmpty(apiKey)) {
            log.debug("使用配置文件中的DashScope API密钥");
            return apiKey;
        }

        // 配置文件未配置时，读取系统环境变量
        String envApiKey = System.getenv("DASHSCOPE_API_KEY");
        if (StringUtils.isEmpty(envApiKey)) {
            String errorMsg = "DashScope API密钥缺失！请通过以下方式配置：\n" +
                    "1. 在application.yml中添加：dashscope.api-key: 你的密钥\n" +
                    "2. 设置系统环境变量：DASHSCOPE_API_KEY=你的密钥";
            log.error(errorMsg);
            throw new NoApiKeyException(); // 抛出SDK原生异常
        }

        log.debug("使用系统环境变量中的DashScope API密钥");
        return envApiKey;
    }

    /**
     * 解析API响应（严格使用SDK类型的getter方法，无强制类型转换）
     * @param apiResult SDK返回的原始结果对象
     * @return 图片URL
     */
    private String parseApiResponse(ImageSynthesisResult apiResult) {
        // 校验结果非空
        if (apiResult == null) {
            throw new RuntimeException("API返回结果为空，请检查网络或SDK版本");
        }

        // 1. 解析核心输出字段（ImageSynthesisOutput类型，非Map）
        ImageSynthesisOutput output = apiResult.getOutput();
        if (output == null) {
            throw new RuntimeException("API响应缺少核心字段：output");
        }

        // 2. 获取任务基本信息（调用getter方法，避免硬编码字段名）
        String taskId = output.getTaskId();
        String taskStatus = output.getTaskStatus();
        log.info("图片生成任务：ID={}, 状态={}", taskId, taskStatus);

        // 3. 处理任务失败场景（补充错误码和错误信息）
        if (!"SUCCEEDED".equals(taskStatus)) {
            String errorCode = output.getCode();
            String errorMsg = output.getMessage();
            throw new RuntimeException(String.format(
                    "图片生成失败！任务ID=%s, 状态=%s, 错误码=%s, 错误信息=%s",
                    taskId, taskStatus, errorCode, errorMsg
            ));
        }

        List<Map<String, String>> imageResults = output.getResults();
        if (imageResults == null || imageResults.isEmpty()) {
            throw new RuntimeException("任务成功但未返回图片数据，任务ID=" + taskId);
        }

        // 提取第一张图片的URL：直接从 Map<String, String> 中获取（值是String类型，无需强转）
        Map<String, String> firstImageMap = imageResults.get(0);
        String imageUrl = firstImageMap.get("url"); // 直接获取String类型的URL，无类型问题
        if (StringUtils.isEmpty(imageUrl)) {
            throw new RuntimeException("图片数据缺少URL字段，任务ID=" + taskId);
        }

        // 5. 解析用量信息（ImageSynthesisUsage类型，非Map）
        parseUsageInfo(apiResult.getUsage());

        // 6. 返回结果
        log.info("图片生成成功，URL：{}", imageUrl);
        return imageUrl;
    }

    /**
     * 解析图片生成用量（直接使用ImageSynthesisUsage的getter方法）
     * @param usage SDK返回的用量对象
     */
    private void parseUsageInfo(ImageSynthesisUsage usage) {
        if (usage == null) {
            log.warn("API响应缺少用量信息（usage字段）");
            return;
        }

        // 调用SDK提供的getter方法获取生成图片数量（避免Map强转）
        Integer generatedImageCount = usage.getImageCount();
        log.info("图片生成用量：本次生成图片数量={}", generatedImageCount != null ? generatedImageCount : 0);
    }
}